<!--
 * @Description: 
 * @Version: 2.0
 * @Autor: swc
 * @Date: 2024-07-26 08:45:52
 * @LastEditors: swc shanwenchao12138@163.com
 * @LastEditTime: 2025-09-08 20:58:53
-->

<template>
  <div class="approval-info" :style="showAnimation">
    <div class="back"></div>
    <div class="front">
      <div class="box">
        <div class="header">
          <div class="title">标题</div>
          <div class="close-btn" @click="hide({ action: 'read' })">
            <Icon type="ios-close" />
          </div>
        </div>
        <div class="main">
          <c-flowchart
            ref="graph"
            :config="stepsBpmnCf"
            v-if="onlyFlow"
          ></c-flowchart>
          <Split v-model="split" v-else>
            <template #left>
              <c-flowchart ref="graph" :config="stepsBpmnCf"></c-flowchart>
            </template>
            <template #right>
              <div class="body">
                <div class="center">
                  <Tabs value="approvalData">
                    <TabPane
                      :label="$srv.getI18nByValue('审批数据')"
                      name="approvalData"
                    >
                      <div class="tabContaniner" v-if="bgConfig">
                        <component
                          :is="openCompName"
                          v-bind="{
                            config: bgConfig,
                            regCustEventName: regCustEventName,
                            listenType: 'magicbox'
                          }"
                          ref="openCompRef"
                          @mounted="onMounted"
                        >
                        </component>
                      </div>
                    </TabPane>
                    <TabPane
                      :label="$srv.getI18nByValue('审批信息')"
                      name="approvalInfo"
                      ><div class="tabContaniner">
                        <Form
                          ref="approvalData"
                          :model="appointApprovalData"
                          :label-width="80"
                        >
                          <FormItem label="批注" prop="annotations">
                            <Input
                              type="textarea"
                              disabled
                              v-model="appointApprovalData.annotations"
                              :rows="8"
                              placeholder="请输入批注..."
                            />
                          </FormItem>
                        </Form>
                      </div>
                    </TabPane>
                    <TabPane
                      :label="$srv.getI18nByValue('审批提交')"
                      name="approvalSubmit"
                    >
                      <div class="tabContaniner">
                        <Form
                          ref="approvalForm"
                          :model="approvalData"
                          :label-width="80"
                        >
                          <FormItem label="批注" prop="annotations">
                            <Input
                              :disabled="isView"
                              type="textarea"
                              v-model="approvalData.annotations"
                              :rows="8"
                              placeholder="请输入批注..."
                            />
                          </FormItem>
                          <FormItem>
                            <Button
                              type="primary"
                              :disabled="isView"
                              @click="handleSubmit"
                            >
                              {{ $srv.getI18nByValue('提交') }}
                            </Button>
                          </FormItem>
                        </Form>
                      </div>
                    </TabPane>
                  </Tabs>
                </div>
                <div class="right">
                  <div
                    :class="['button', !canHandle ? 'disabled' : '']"
                    v-for="(item, idx) in buttonList"
                    v-show="item.isShow"
                    :key="idx"
                    @click="onButtonClick(item, $event)"
                  >
                    {{ $srv.getI18nByValue(item.title) }}
                  </div>
                </div>
              </div>
            </template>
          </Split>
        </div>
        <o-modal
          v-model="noteModal"
          :title="$srv.getI18nByValue('批注')"
          :size="[400, 300]"
          :mask="true"
          :tap-close="true"
          :keep-alive="true"
          @on-ok="noteOk()"
          @on-close="noteHide()"
        >
          <div class="init-container" slot="content">
            <Input type="textarea" :rows="8" placeholder="请输入批注..." />
          </div>
        </o-modal>
        <!-- 选择人员 -->
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import oModal from '@/components/base/modal/o-modal/index.vue';
import {
  I_cmd,
  N_cFlowchart,
  N_oApprovalInfo,
  T_cmd,
  T_srv,
  Tsrv,
  ifs,
  initButtons,
  stepsBpmnConfig,
  ts,
  vue
} from './config';

@T_srv.comp({
  components: {
    oModal
  }
})
export default class oApprovalInfo extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.prop() config: N_oApprovalInfo.config;

  @T_srv.prop() id: string;

  // @T_srv.watch('config')
  // onConfigChange(val: any) {
  //   this.getLiaisonInfo();
  // }

  /* 组件名 */
  private name: string = 'oApprovalInfo';

  private funName: string = '';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  private isShow: boolean = false;

  private showAnimation: any = {};

  private split = 0.3;

  //  审核流程条目数据
  public bpmnData: any = null;

  //  审核流程图——图数据
  public graphData: any = null;

  /*
   * 被审核的数据
   */
  private originData: any = null;

  // 内部联络单明细 （DSL数据）
  private approvalNodes: Array<any> = [];

  // 画布实例
  // private graph: N_cFlowchart.cFlowchart = null;
  private graph: any = null;

  private noteModal: boolean = false;

  private stepsBpmnCf: N_cFlowchart.I_conf = null;

  private buttonList: Array<N_oApprovalInfo.I_button> = initButtons();

  public curApprover: any = null;

  private nextApprover: Array<any>;

  private prevApprover: Array<any>;

  public approvalTableName: string = '';

  // 批注
  public approvalData: any = {};

  public appointApprovalData: any = {};

  public openCompName: string = '';

  public bgConfig: any = null;

  // public regCustEventName: Array<N_oBaseGrid.I_regCustEventName | string> = [];
  public regCustEventName: Array<string> = [];

  private bgRef: any = null;

  // 联络单标题
  private liaisonTitle: string = '';

  // 联络单ID
  private liaisonID: string = '';

  // 联络单 数据
  private liaisonData: any = null;

  private isView: boolean = true;

  private selectebleApproversList: Array<any> = [];

  private selectedUsers: Array<any> = [];

  private originFunConfig: any = null;

  get onlyFlow() {
    return this.config?.onlyFlow;
  }

  get canHandle() {
    // 此时 如果 有节点的序号 大于 自身节点序号的 那么 同样不能编辑
    let isMax = true;
    let isApprovaling = true;
    const approvalNodes = this.approvalNodes;
    if (
      Tsrv.noValue(approvalNodes) ||
      Tsrv.noValue(this.curApprover) ||
      Tsrv.noValue(this.liaisonData)
    ) {
      return false;
    }
    for (let i = 0; i < approvalNodes.length; i++) {
      const el = approvalNodes[i];
      if (
        Tsrv.utils.isNumber(el?.sn) &&
        Tsrv.utils.isNumber(this.curApprover?.sn)
      ) {
        if (el.sn > this.curApprover.sn) {
          isMax = false;
          break;
        }
      }
    }
    isApprovaling = this.liaisonData?.f_status === 0;
    return this.curApprover?.confirm === 0 && isMax && isApprovaling;
  }

  get isCanSelectNode() {
    return this.selectebleApproversList.length > 0;
  }

  get isCanShow() {
    return !Tsrv.noValue(this.config?.msgConfig?.liaisonID);
  }

  @T_srv.ref('openCompRef') openCompRef: any;

  // private annotations

  created() {
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    if (this.isCanShow) {
      this.show();
    }
  }

  private init() {
    this.funName = this.name; // 当前配置中的功能名
    if (Tsrv.noValue(this.config?.msgConfig?.liaisonID)) {
      this.$msg(Tsrv.getI18nByValue('未传入联络单ID'));
      return;
    }
    this.liaisonID = this.config.msgConfig.liaisonID;
    const stepsBpmnCf = stepsBpmnConfig();
    stepsBpmnCf.regEvent = this.GT_command.regGraphEvents;
    this.stepsBpmnCf = stepsBpmnCf;
    this.getLiaisonInfo();
  }

  private getLiaisonInfo() {
    const _config = this.config;
    if (_config) {
      // 根据config内部联络单的row信息————得到对应bpmn的row数据等到图数据
      if (_config.msgConfig.liaisonID) {
        Promise.all([
          this.GT_command.getLiaisonDet(),
          this.GT_command.getLiaison()
        ]).then(responses => {
          this.setApprovalNodes(responses[0]);
          this.getComponentConfig(responses[1]);
          this.addLiaisonLog(1, `${Tsrv.getUserName()} 查看了该审批内容。`);
          // this.show();
        });
      } else {
        this.$Message.error({ content: '未传入联络单ID' });
      }
    } else {
      this.$Message.error({ content: '未传入config' });
    }
  }

  /**
   * @description: （1、获取所有审批节点数据，2、找到当前审批人数据）
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:29:33
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private setApprovalNodes(d: any) {
    const [b, res, rows, msg] = d;
    if (!b) {
      msg && this.$msg(msg);
    }
    if (rows.length !== 0) {
      rows.forEach(item => {
        if (Tsrv.noValue(item?.approver)) {
          item.approver = [];
        } else {
          item.approver = JSON.parse(item.approver);
        }
        item.father_data = JSON.parse(item.father_data);
        item.son_data = JSON.parse(item.son_data);
        item.graph_data = JSON.parse(item.graph_data);
      });
    }
    this.approvalNodes = rows;
    this.GT_command.setApprovalNodes(rows);
    this.getcurApprover(rows);
    // 判断当前节点 能否有条件 手动选择 下级节点
    // 若有则找出来
    this.getSelectableNodes();
    // 控制“选择用户”按钮的现实与隐藏
    // ☆☆☆ 业务不需要此操作 先注释
    // for (let i = 0; i < this.buttonList.length; i++) {
    //   const el = this.buttonList[i];
    //   if (el.value === 'select') {
    //     el.isShow = !!this.isCanSelectNode;
    //   }
    // }
  }

  /**
   * @description: 获取阻组件配置信息
   * @description: 1、整理画布数据
   * @description: 2、被审核数据组件的配置信息和数据
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:57:25
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private getComponentConfig(d: any) {
    const [b, res, rows, msg] = d;
    if (!b) {
      msg && this.$msg(msg);
    }
    if (rows.length > 0) {
      if (
        !Tsrv.noValue(rows[0]?.f_data) &&
        Tsrv.utils.isJSONString(rows[0].f_data)
      ) {
        this.originData = JSON.parse(rows[0].f_data);
      }
      this.liaisonData = rows[0];
      const liasionStatus = rows[0].f_status;
      if (liasionStatus !== 0) {
        let msgTip = '';
        if (liasionStatus === 1) {
          msgTip = '此审批流程已结束';
        }
        if (liasionStatus === 9) {
          msgTip = '此审批流程已暂停';
        }
        if (liasionStatus === 11) {
          msgTip = '此审批流程已作废';
        }
        this.$msg(Tsrv.getI18nByValue(`${msgTip}！`));
        this.hide();
        return;
      }
      this.liaisonTitle = rows[0]['title'];
      this.getBPMN(rows[0]?._sys_graph_id).then(resp => {
        if (resp) {
          this.initGraph();
          setTimeout(() => {
            this.handleNodeStyle();
          }, 200);
          const funName = resp['m2o|_sys_fun_id|_sys_fun|title'];
          this.approvalTableName = funName;
          //  && !this.onlyFlow
          if (!Tsrv.noValue(funName) && !this.onlyFlow) {
            this.getBgConfig(funName).then(r => {
              if (r) {
                // 过滤目标数据
                this.filterTargetData(this.openCompRef, this.openCompName);
                // if (this.openCompName === Tsrv.globalVar.compName.BASE_GRID) {
                // }
              }
            });
          }
        } else {
          this.$msg(Tsrv.getI18nByValue('审批流程图请求报错'));
        }
      });
    } else {
      this.$msg(Tsrv.getI18nByValue('未找到该联络单数据'));
    }
  }

  // 审批源数据的过滤
  private filterTargetData(compRef: any, compName: string, isReload = false) {
    if (compName === Tsrv.globalVar.compName.BASE_GRID) {
      const approvalDataIds = [];
      if (Array.isArray(this.originData)) {
        approvalDataIds.push(...this.originData);
      }
      const _filter: ifs.I_filter = new ts.T_filter();
      _filter.filter = {
        id: { $in: approvalDataIds }
      };
      // this.openCompRef.GT_editor.addInitFilter(_filter);
      compRef.GT_editor.setInjectFilter(_filter);
      if (isReload) compRef.GT_editor.loadTableData();
    } else if (compName === Tsrv.globalVar.compName.BASE_PANEL) {
      const approvalDataIds = [];
      if (Array.isArray(this.originData)) {
        // this.originData.forEach(item => {
        //   approvalDataIds.push(new ts.T_fv().setField('id').setValue(item));
        // });
        approvalDataIds.push(
          new ts.T_fv().setField('id').setValue(this.originData[0])
        );
      }
      typeof this.originData === 'string' &&
        approvalDataIds.push(
          new ts.T_fv().setField('id').setValue(this.originData)
        );
      // this.openCompRef.GT_command.addInitFilter(approvalDataIds);
      compRef.GT_command.addInitFilter(approvalDataIds);
    } else if (compName === Tsrv.globalVar.compName.LAYOUT) {
      setTimeout(() => {
        const comp = Tsrv.compBox.getCompsRegexMathName(
          this.approvalTableName
        )[0]?.comp;
        const name = Tsrv.utils.toLine(comp?.G_compName);
        if (!Tsrv.noValue(compName)) {
          this.filterTargetData(comp, name, true);
        }
      }, 0);
    }
  }

  /**
   * @description: 根据流程图id 获取流程图数据、
   * @param {*} id 流程图id
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:11:18
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private getBPMN(id: string): Promise<boolean> {
    return new Promise((resolve, reject) => {
      if (Tsrv.noValue(id)) {
        resolve(false);
        return;
      }
      const dbType = Tsrv.globalVar.dbType.MYSQL;
      const tableName = Tsrv.globalVar.tableName.BPMN_LIB;
      const gpd = new ts.T_getPartDataArg();
      gpd.setFunName(tableName).setLang(this.$i18n.locale || 'en-US');
      gpd.setPage(1, 99999).setDbType(dbType);
      gpd.setFilter({
        id: {
          $in: [id]
        }
      });
      Tsrv.getData<any, ifs.I_getPartDataArg>(gpd)
        .then(([b, res, rows, msg]) => {
          if (!b) {
            msg && this.$msg(msg);
            resolve(false);
          }
          if (rows.length > 0) {
            this.bpmnData = rows[0];
            const unzipResp = wUnZipStr(rows[0].graph_data);
            if (unzipResp.isErr()) {
              throw new Error(unzipResp.getErrMsg());
            }
            this.graphData = unzipResp.getReturnData('data');

            // this.initGraph();
            // this.handleNodeStyle();
            resolve(rows[0]);
          } else {
            resolve(false);
          }
        })
        .catch(er => {
          console.error('获取BPMN图库数据失败', er);
        });
    });
  }

  private initGraph() {
    if (!Tsrv.noValue(this.graphData)) {
      this.graph = this.$refs.graph;
      let graphData = this.graphData as string;
      if (!Tsrv.utils.isJSONString(graphData)) {
        graphData = JSON.stringify(graphData);
      }
      this.graph.reLoadDataFromJson(graphData);
      this.GT_command.setGraph(this.graph.graph);
      setTimeout(() => {
        this.graph.zoomToFit({
          padding: 20,
          preserveAspectRatio: true
        });
      }, 0);
    }
  }

  /**
   * @description: 根据表名名获取 配置信息 获取审批数据
   * @param {*} tableName 功能名称
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:11:18
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private getBgConfig(tableName: string): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.$store
        .dispatch('getLayoutConfigAsync', {
          funid: null,
          field: tableName,
          // type: 'component'
          type: 'layout'
        })
        .then(async res => {
          if (res && Tsrv.getx(res, 'current.config', false)) {
            const current = Tsrv.utils.clone(res.current, true);
            const cfg = Tsrv.utils.clone(current.config, true);

            this.openCompName =
              current.name === 'BaseGrid'
                ? Tsrv.globalVar.compName.BASE_GRID
                : current.name === 'BasePanel'
                ? Tsrv.globalVar.compName.BASE_PANEL
                : current.name === 'layout'
                ? Tsrv.globalVar.compName.LAYOUT
                : '';
            if (Tsrv.noValue(this.openCompName)) {
              resolve(false);
            } else {
              setTimeout(() => {
                this.getOriginFunConfig();
              }, 0);
              if (this.openCompName === Tsrv.globalVar.compName.LAYOUT) {
                this.closeFunBtns(current);
                this.bgConfig = current;
                resolve(true);
              } else {
                this.handleFunCfg(cfg);
                this.bgConfig = cfg;
                resolve(true);
              }
            }
          } else {
            resolve(false);
          }
        });
    });
  }

  private getOriginFunConfig() {
    if (this.openCompName === Tsrv.globalVar.compName.LAYOUT) {
      const comp = Tsrv.compBox.getCompsRegexMathName(this.approvalTableName)[0]
        ?.comp;
      if (!Tsrv.noValues(comp, comp?.config)) {
        this.originFunConfig = Tsrv.utils.clone(comp.config);
      }
    } else {
      if (!Tsrv.noValues(this.openCompRef, this.openCompRef?.config)) {
        this.originFunConfig = Tsrv.utils.clone(this.openCompRef.config);
      }
    }
  }

  // 递归关闭功能按钮权限
  private closeFunBtns(config) {
    if (Tsrv.noValue(config)) return;
    if (config.type === 'layout') {
      this.closeFunBtns(config.config.first);
      this.closeFunBtns(config.config.second);
    } else {
      if (config.name === 'BaseTab') {
        config.config.panels.forEach(item => {
          this.closeFunBtns(item.content);
        });
      }
      this.handleFunCfg(config.config);
    }
  }

  /**
   * @description: 二次整理被审批功能的 config
   * @param {*} cfg
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:11:18
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private handleFunCfg(cfg: any) {
    // 限制可显示的按钮
    // default export exportXML globalSearch import print refresh
    const allowBtns = [
      // 'globalSearch',
      // 'export',
      // 'import',
      // 'print',
      // 'refresh',
      // 'jumpFirst',
      // 'jumpLast',
      // 'next',
      // 'previous',
      'default'
    ];
    if (Tsrv.noValue(cfg)) return;
    const btns = cfg?.toolbar;
    if (Tsrv.noValue(btns)) return;
    Object.keys(btns).forEach(key => {
      if (!allowBtns.includes(key)) {
        btns[key] = false;
      }
    });
  }

  /**
   * @description: 获取当前审批人
   * @param {*} nodes
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:11:18
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private getcurApprover(nodes: Array<any>) {
    //
    if (!Array.isArray(nodes) || nodes.length === 0) return;
    // const approvedNodes = nodes.filter(item => item.confirm === 1);
    const approvedNodes = nodes;
    // if (Tsrv.noValue(approvedNodes)) {
    //   this.curApprover = nodes.fi;
    //   return;
    // }
    let maxSn = approvedNodes[0].sn;
    for (let i = 1; i < approvedNodes.length; i++) {
      if (approvedNodes[i].sn > maxSn) {
        maxSn = approvedNodes[i].sn;
      }
    }
    const result = [];
    for (let i = 0; i < approvedNodes.length; i++) {
      if (approvedNodes[i].sn === maxSn) {
        result.push(approvedNodes[i]);
      }
    }
    for (let j = 0; j < result.length; j++) {
      const el = result[j];
      if (
        el.f_type === 0 &&
        el?.graph_data?.checker?.value === Tsrv.getUserNo()
      ) {
        this.curApprover = el;
      }
      if (el.f_type === 2 && !Tsrv.noValue(el?.approver)) {
        // const fd = el.approver.find(f => f?.userNO === Tsrv.getUserNo());
        // if (fd) this.curApprover = el;
        const fdK = el.approver.findIndex(f => f?.userNO === Tsrv.getUserNo());
        if (fdK > -1) this.curApprover = el;
      }
    }
    if (!Tsrv.noValue(this.curApprover)) {
      this.isView = false;
    }
    // 节点信息
    if (!Tsrv.noValue(this.curApprover) && this.curApprover?.content !== null) {
      this.approvalData = JSON.parse(this.curApprover.content);
    }
  }

  // 判断当前节点 能否有条件 手动选择 下级节点
  private getSelectableNodes() {
    if (!Tsrv.noValue(this.curApprover)) {
      const sonNodes = this.curApprover.son_data;
      // 用户/用户组节点最多只能有一个子级节点
      if (!Tsrv.noValue(sonNodes)) {
        const sonNodeData = sonNodes[0];
        // sonNodeData是路由节点
        if (sonNodeData?.type === 1) {
          const sonNode = this.approvalNodes.find(
            item => item.f_code === sonNodeData.nodeCode
          );
          const aimNodes = sonNode.son_data;
          if (!Tsrv.noValue(aimNodes)) {
            const selectebleApprovers = [];
            for (let i = 0; i < aimNodes.length; i++) {
              const el = aimNodes[i];
              if (el?.type !== 1) {
                const findNode = this.approvalNodes.find(
                  item => item.f_code === el?.nodeCode
                );
                if (findNode) selectebleApprovers.push(findNode);
              }
            }
            this.selectebleApproversList = selectebleApprovers.map(el => {
              return {
                status: el.confirm,
                type: el.f_type,
                nodeCode: el.f_code,
                data: { ...el.graph_data },
                id: el.id,
                sn: el.sn
              };
            });
          }
        } else if (sonNodeData?.type === 2) {
          const findNode = this.approvalNodes.find(
            item => item.f_code === sonNodeData?.nodeCode
          );
          if (findNode) {
            this.selectebleApproversList.push({
              status: findNode.confirm,
              type: findNode.f_type,
              nodeCode: findNode.f_code,
              data: { ...findNode.graph_data },
              id: findNode.id,
              sn: findNode.sn
            });
          }
        }
      }
    }
  }

  /**
   * @description: 根据审批节点信息 渲染 审批节点样式
   * @param {*}
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:11:18
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  private handleNodeStyle() {
    const graph: any = this.$refs.graph;
    const x6Graph: N_cFlowchart.x6Graph = graph.graph;
    const nodes = x6Graph.getNodes();
    const approvalNodes: Array<any> = this.approvalNodes;
    nodes.forEach(node => {
      // const data = node.getData();
      const nodeProp = node.getProp();
      if (nodeProp.shape === 'bpmn-begin' || nodeProp.shape === 'bpmn-end') {
        // node.updateAttrs({
        //   body: {
        //     fill: '#57a3f3',
        //     stroke: '#000',
        //     strokeWidth: 1,
        //     rx: 26,
        //     ry: 26
        //   }
        // });
        node.setAttrByPath('body/fill', '#57a3f3');
      } else {
        //
        const approvalNode = approvalNodes.find(
          // item => item.f_code === nodeProp.id
          item => item.f_code === nodeProp.data.id
        );
        if (approvalNode?.confirm) {
          // node.updateAttrs({
          //   body: {
          //     fill: '#c5c8cef7',
          //     stroke: '#000',
          //     strokeWidth: 1,
          //     rx: 26,
          //     ry: 26
          //   }
          // });
          node.setAttrByPath('body/fill', '#c5c8cef7');
        }
        if (approvalNode?.id === this.curApprover?.id && this.canHandle) {
          // node.updateAttrs({
          //   body: {
          //     fill: '#4bff2d',
          //     stroke: '#000',
          //     strokeWidth: 1,
          //     rx: 26,
          //     ry: 26
          //   }
          // });
          node.setAttrByPath('body/fill', '#4bff2d');
        }
      }
    });
  }

  public onButtonClick(btn: N_oApprovalInfo.I_button, e) {
    const key = btn.value;
    if (!this.canHandle) {
      return;
    }
    switch (key) {
      case 'pass':
        this.handlePass();
        break;
      case 'reject':
        this.handleReject();
        break;
      case 'annotate':
        this.annotate();
        break;
      case 'revoke':
        this.revoke();
        break;
      case 'select':
        this.selectUsers();
        break;
      case 'debug':
        this.debug();
        break;
      default:
        break;
    }
  }

  private debug() {
    // this.usersSelectModal = true;
    // _sys_interaction_default_resp
    // this.GT_command.executeEvent('_sys_interaction_default_resp', {})
    //   .then(r => {
    //     console.log(r);
    //   })
    //   .catch(e => {
    //     console.error(e);
    //   });
    // console.log(this.curApprover);
    console.log(this.getEventParams());
    // this.curApprover
  }

  // // 选择用户弹窗 确定按钮
  // private usersSelectOk() {
  //   this.usersSelectHide();
  //   // 1、保存好已经选择的下级用户/用户组节点
  //   // const uesrsSelectInstance = this.GT_compBox.getCompMergeName(
  //   //   this.G_compID,
  //   //   'oUsersSelect'
  //   // );
  //   // const selectedUsers = uesrsSelectInstance.getSelectedUsers();
  //   const selectedUsers = (this.$refs.usersSelectRef as any).getSelectedUsers();
  //   this.selectedUsers = selectedUsers;
  //   // 2、更新节点数据
  //   // 3、执行审核通过行为
  //   this.handleApproveActions(true, {}, this.approvalPass);
  // }

  // // 选择用户弹窗 确定按钮
  // private usersSelectHide() {
  //   this.usersSelectModal = false;
  // }

  private selectUsers() {
    // this.openUsersSelect();
    if (this.isCanSelectNode) {
      const modelConfig = {
        optionsList: this.selectebleApproversList
      };
      Tsrv.utils
        .createModal('cSelectApprovers', modelConfig)
        .then(r => {
          if (!Tsrv.noValue(r)) {
            this.selectedUsers = r;
            this.handleApproveActions(true, {}, this.approvalPass);
          }
        })
        .catch(e => {
          console.error(e);
          this.$msg(e);
        });
    }
  }

  private handlePass() {
    if (this.isCanSelectNode && Tsrv.noValue(this.selectedUsers)) {
      this.$Modal.confirm({
        title: Tsrv.getI18nByValue('是否选择下级审批人') as string,
        content: Tsrv.getI18nByValue('可自主选择下级审批人') as string,
        onOk: () => {
          // this.openUsersSelect();
          this.selectUsers();
        },
        onCancel: () => {
          this.handleApproveActions(true, {}, this.approvalPass);
          // this.approvalPass();
        }
      });
    } else {
      this.handleApproveActions(true, {}, this.approvalPass);
      // this.approvalPass();
    }
  }

  private handleReject() {
    this.handleApproveActions(false, {}, this.approvalReject);
  }

  /**
   * 审批通过处理函数
   *
   * 1. 获取下一审批节点信息
   * 2. 如果是最终节点：
   *    - 更新审批节点状态
   *    - 更新联络单状态为"审批结束"
   *    - 添加审批结束日志
   * 3. 如果不是最终节点：
   *    - 更新审批节点状态
   *    - 给下一审批人发送通知消息
   *    - 添加审批通过日志
   *
   * @returns {Promise<boolean>} 返回处理结果的Promise
   */
  // private approvalPass(): Promise<boolean> {
  //   return new Promise((resolve, reject) => {
  //     this.GT_command.getNextApprover().then(res => {
  //       const [isEnd, changes, nextUsers] = res;
  //       if (isEnd) {
  //         // 结束
  //         this.GT_command.updateApprNodesStatus(nextNodes).then(resp => {
  //           if (resp) {
  //             this.GT_command.updateLiaisonStatus(1).then(r => {
  //               if (r) {
  //                 // this.addLiaisonLog(1, '审批结束');
  //                 this.GT_command.addLiaisonLog(1, '审批结束').then(r1 => {
  //                   resolve(true);
  //                 });
  //                 // 审核通过，修改被审核数据状态
  //                 this.GT_command.updateApproveStatus(
  //                   this.approvalTableName,
  //                   this.originData
  //                 );
  //               }
  //             });
  //           }
  //         });
  //       } else {
  //         const approvers = nextNodes.filter(item => item.type === 0);
  //         // 1、修改 【审批人、条件】 的状态
  //         this.GT_command.updateApprNodesStatus(nextNodes).then(r => {
  //           if (r) {
  //             // 2、发送消息给下一个人
  //             for (let i = 0; i < approvers.length; i++) {
  //               const ele = approvers[i];
  //               // 发消息==>审批人
  //               this.GT_command.addLiaisonLog(3, '通过');
  //               const approver = ele?.nodeData?.checker?.value;
  //               if (!Tsrv.noValue(approver)) {
  //                 this.GT_command.sendMessage(
  //                   approver,
  //                   this.liaisonTitle,
  //                   this.liaisonID
  //                 );
  //               }
  //             }
  //             resolve(true);
  //           }
  //         });
  //       }
  //       this.hide();
  //     });
  //   });
  // }

  /**
   * 审批通过处理函数
   *
   * 1. 获取下一审批节点信息
   * 2. 如果是最终节点：
   *    - 更新审批节点状态
   *    - 更新联络单状态为"审批结束"
   *    - 添加审批结束日志
   * 3. 如果不是最终节点：
   *    - 更新审批节点状态
   *    - 给下一审批人发送通知消息
   *    - 添加审批通过日志
   *
   * @returns {Promise<boolean>} 返回处理结果的Promise
   */
  private approvalPass(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      this.GT_command.getNextApprover().then(res => {
        const [isEnd, changes, nextUsers] = res;
        if (isEnd) {
          // 结束
          this.GT_command.updateApprovalNodesData(changes).then(resp => {
            if (resp) {
              this.GT_command.updateLiaisonStatus(1).then(r => {
                if (r) {
                  // 审核通过，修改被审核数据状态
                  this.GT_command.updateApproveStatus(
                    this.approvalTableName,
                    this.originData
                  ).then(r1 => {
                    if (r1) {
                      resolve(true);
                      this.hide({ action: 'delete' });
                      this.GT_command.addLiaisonLog(
                        3,
                        `${Tsrv.getUserName()} 通过了该层审批，审批到此结束！`
                      );
                    }
                  });
                }
              });
            }
          });
        } else {
          // 1、修改 【审批人、条件】 的状态
          this.GT_command.updateApprovalNodesData(changes).then(r => {
            if (r) {
              // 2、发送消息给下一个人
              this.GT_command.addLiaisonLog(
                3,
                `${Tsrv.getUserName()} 通过了该层审批，并且向下流转。`
              );
              this.hide({ action: 'delete' });
              for (let i = 0; i < nextUsers.length; i++) {
                const ele = nextUsers[i];
                if (!Tsrv.noValue(ele?.userNO)) {
                  this.GT_command.sendMessage(
                    ele.userNO,
                    this.liaisonTitle,
                    this.liaisonID
                  );
                }
              }
              resolve(true);
            }
          });
        }
      });
    });
  }

  // private approvalReject(): Promise<boolean> {
  //   return new Promise((resolve, reject) => {
  //     const curApprover = this.curApprover;
  //     const curNode = {
  //       id: curApprover?.id,
  //       type: curApprover.f_type,
  //       nodeID: curApprover.f_code,
  //       confirm: curApprover.confirm,
  //       nodeData: curApprover.graph_data ?? null,
  //       previousNodes: curApprover.father_data ?? [],
  //       subsequentNodes: curApprover.son_data ?? []
  //     };
  //     const [isBegin, nextNodes] = this.GT_command.getPrevApprover(curNode);
  //     if (isBegin) {
  //       // 后续决定 看是否 需要  “撤回审批”  功能
  //       this.$Message.info({ content: '已是第一级审批人', closable: true });
  //       resolve(false);
  //       return;
  //     }
  //     // 1、修改 【审批人、条件】 的状态  还有  序号改为 0
  //     const approvers = nextNodes.filter(item => item.type === 0);
  //     this.GT_command.updateApprNodesStatus(nextNodes, 0).then(r => {
  //       if (r) {
  //         // 2、发送消息给上一个人（这里审批人应该只有一个,）
  //         const ele = approvers[0];
  //         // 发消息==>审批人
  //         this.GT_command.addLiaisonLog(4, '驳回');
  //         const approver = ele?.nodeData?.checker?.value;
  //         if (!Tsrv.noValue(approver)) {
  //           this.GT_command.sendMessage(
  //             approver,
  //             this.liaisonTitle,
  //             this.liaisonID
  //           );
  //         }
  //         resolve(true);
  //       }
  //     });
  //     this.hide();
  //   });
  // }
  private approvalReject(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      const curApprover = this.curApprover;
      const curNode = {
        id: curApprover?.id,
        type: curApprover.f_type,
        nodeID: curApprover.f_code,
        confirm: curApprover.confirm,
        nodeData: curApprover.graph_data ?? null,
        previousNodes: curApprover.father_data ?? [],
        subsequentNodes: curApprover.son_data ?? []
      };
      const curSn = curApprover.sn;
      const [isBegin, nextNodes] = this.GT_command.getPrevApprover(curNode);
      if (isBegin) {
        // 后续决定 看是否 需要  “撤回审批”  功能
        this.$Message.info({ content: '已是第一级审批人', closable: true });
        resolve(false);
        return;
      }
      const changes = [];
      const previousUsers = [];

      // 1、当前节点修改的数据
      const curNodeUpdateData = [];
      curNodeUpdateData.push(
        new ts.T_fv()
          .setField(Tsrv.globalVar.fieldName.ID)
          .setValue(curApprover.id),
        new ts.T_fv().setField('confirm').setValue(0),
        new ts.T_fv().setField('sn').setValue(0)
      );
      if (curApprover.f_type === 2) {
        curNodeUpdateData.push(
          new ts.T_fv().setField('approver').setValue(JSON.stringify([]))
        );
      }
      changes.push(curNodeUpdateData);
      // 2、
      const sameLevelNodes = this.approvalNodes.filter(
        item => item.sn === curApprover.sn
      );
      for (let i = 0; i < sameLevelNodes.length; i++) {
        const el = sameLevelNodes[i];
        if (el.id !== curApprover.id) {
          const nodeUpdateData = [];
          nodeUpdateData.push(
            new ts.T_fv().setField(Tsrv.globalVar.fieldName.ID).setValue(el.id),
            new ts.T_fv().setField('sn').setValue(0)
          );
          if (el.f_type === 2) {
            nodeUpdateData.push(
              new ts.T_fv().setField('approver').setValue(JSON.stringify([]))
            );
          }
          changes.push(nodeUpdateData);
        }
      }
      // 3、上级节点修改的数据
      const isExistCondition = nextNodes.some(el => el.type === 1);
      for (let i = 0; i < nextNodes.length; i++) {
        const el = nextNodes[i];
        const nodeUpdateData = [];
        nodeUpdateData.push(
          new ts.T_fv().setField(Tsrv.globalVar.fieldName.ID).setValue(el.id),
          new ts.T_fv().setField('confirm').setValue(0)
        );
        if (el.type === 0) {
          nodeUpdateData.push(
            new ts.T_fv()
              .setField('sn')
              .setValue(isExistCondition ? curSn - 2 : curSn - 1)
          );
          if (el.confirm) {
            previousUsers.push({
              userID: '',
              userNO: el?.nodeData?.checker?.value ?? '',
              userName: el?.nodeData?.checker?.label ?? ''
            });
          }
        }
        if (el.type === 1) {
          nodeUpdateData.push(new ts.T_fv().setField('sn').setValue(0));
        }
        if (el.type === 2) {
          nodeUpdateData.push(
            new ts.T_fv()
              .setField('sn')
              .setValue(isExistCondition ? curSn - 2 : curSn - 1),
            new ts.T_fv().setField('approver').setValue(JSON.stringify([]))
          );
          if (el.confirm && !Tsrv.noValue(el.approvers)) {
            previousUsers.push(...el.approvers);
          }
        }
        changes.push(nodeUpdateData);
      }
      // 1、修改 【审批人、条件】 的状态  还有  序号改为 0
      this.GT_command.updateApprovalNodesData(changes).then(r => {
        if (r) {
          // 2、发送消息给上一个人（这里审批人应该只有一个,）
          this.GT_command.addLiaisonLog(4, '驳回');
          for (let i = 0; i < previousUsers.length; i++) {
            const ele = previousUsers[i];
            if (!Tsrv.noValue(ele?.userNO)) {
              this.GT_command.sendMessage(
                ele.userNO,
                this.liaisonTitle,
                this.liaisonID
              );
            }
          }
          resolve(true);
        }
      });
      this.hide({ action: 'read' });
    });
  }

  private handleSubmit(): Promise<boolean> {
    return new Promise((resolve, reject) => {
      if (Tsrv.noValue(this.curApprover)) {
        resolve(false);
        return;
      }
      const ctd = new ts.T_ctdArg();
      ctd
        .setTableName(Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET_DET)
        .setDbType(Tsrv.globalVar.dbType.MYSQL);
      ctd.setRule({} as ifs.I_rule);
      const ctdUpdDatas: ifs.I_ctdUpdData[] = [];
      const ctdUpdData = new ts.T_ctdUpdData();
      ctdUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
      const rowData: ifs.I_fv[] = [];
      const filter = { id: this.curApprover.id };
      rowData.push(
        new ts.T_fv()
          .setField('content')
          .setValue(JSON.stringify(this.approvalData))
      );
      ctdUpdData.setFilter(filter);
      ctdUpdData.setRowData(...rowData);
      ctdUpdDatas.push(ctdUpdData);
      ctd.setUpdRecDataMany(...ctdUpdDatas);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        msg && this.$msg(msg);
        if (b) {
          resolve(true);
          this.addLiaisonLog(
            2,
            `审批人 ${Tsrv.getUserName()} 对该审批内容进行了批注`
          );
        } else {
          reject();
        }
      });
    });
  }

  /**
   * 执行审批动作
   * @param isPass 是否通过
   * @param params 传参
   * @param callback 通过 或者 拒绝函数
   */
  public handleApproveActions(
    isPass: boolean,
    params: any,
    callback: () => Promise<boolean>
  ) {
    const actions = this.originFunConfig?.action;
    const name = isPass ? 'Approve' : 'Antiaudit';
    if (Tsrv.noValue(params)) {
      params = this.getEventParams();
    }
    let doEvent = null;
    // if (this.openCompName === Tsrv.globalVar.compName.BASE_GRID) {
    //   doEvent = this.bgRef.GT_editor.doEvent;
    // } else if (this.openCompName === Tsrv.globalVar.compName.BASE_PANEL) {
    //   doEvent = this.bgRef.GT_command.doEvent;
    // }
    // if (Tsrv.noValue(doEvent)) {
    //   console.error('doEvent is null');
    //   return;
    // }
    doEvent = this.GT_command.executeEvent;
    if (actions[`before${name}`]) {
      doEvent(actions[`before${name}`], params).then(_ => {
        if (_) {
          callback().then(res => {
            if (res && actions[`after${name}`]) {
              doEvent(actions[`after${name}`], params);
            }
          });
        }
      });
    } else {
      callback().then(r => {
        if (r && actions[`after${name}`]) {
          doEvent(actions[`after${name}`], params);
        }
      });
    }
  }

  private getEventParams(): any {
    return {
      funName: this.approvalTableName,
      liasionID: this.liaisonID,
      graphID: this.graphData.id,
      // 当前联络单明细 ID
      detRowID: this.curApprover.id,
      // 被审批的数据
      approvalData: this.originData,
      // 操作信息
      operateInfo: {
        // 当前审批人信息
        approver: {
          userID: Tsrv.getUserID(),
          userNO: Tsrv.getUserNo(),
          userName: Tsrv.getUserName()
        }
      }
    };
  }

  public nodeClick(nodeID: string) {
    const current = this.approvalNodes.find(item => item.f_code === nodeID);
    if (Tsrv.noValue(current)) {
      return;
    }
    // // 当前节点得 内容
    const content = current.content;
    if (content === null) {
      this.appointApprovalData = {};
    }
    if (Tsrv.utils.isJSONString(content)) {
      this.appointApprovalData = JSON.parse(content);
    }
  }

  private annotate() {
    this.noteModal = true;
  }

  private revoke() {
    this.GT_command.revokeApproval();
  }

  private noteOk() {
    // 修改批注操作
    this.noteHide();
  }

  private noteHide() {
    this.noteModal = false;
  }

  private addLiaisonLog(type: number, info: string) {
    this.GT_command.addLiaisonLog(type, info);
  }

  public onMounted(e) {
    this.bgRef = e;
    // if (this.openCompName === Tsrv.globalVar.compName.BASE_PANEL) {
    //   }
    // this.filterTargetData(this.openCompRef, this.openCompName);
    this.$emit('bg-mounted', e);
  }

  public show() {
    const that = this;
    this.showAnimation = {
      display: 'block',
      // 'z-index': 102 + this.id
      'z-index': 202 + this.id
    };
    setTimeout(() => {
      that.showAnimation = {
        display: 'block',
        opacity: 1,
        // 'z-index': 102 + this.id
        'z-index': 202 + this.id
      };
    }, 10);
  }

  public hide(param: N_oApprovalInfo.I_hideParam = { action: 'read' }) {
    const that = this;
    this.showAnimation = {
      display: 'block',
      opacity: 0,
      // 'z-index': 102 + this.id
      'z-index': 202 + this.id
    };
    setTimeout(() => {
      that.showAnimation = {
        display: 'none',
        // 'z-index': 102 + this.id
        'z-index': 202 + this.id
      };
      this.$bus.$emit(`modal_${this.id}`, param);
    }, 200);
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }
}
</script>
<style lang="scss" scoped>
// $top-height: 100px;
//框架
.approval-info {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  opacity: 0;
  display: none;
  transition: ease-in-out 0.2s;
  .back {
    background-color: rgba(0, 0, 0, 0.5);
    width: 100%;
    height: 100%;
  }
  .front {
    position: absolute;
    width: calc(100% - 30px);
    height: calc(100% - 30px);
    top: 15px;
    left: 15px;
    .box {
      width: 100%;
      height: 100%;
      background-color: #fff;
      display: flex;
      flex-direction: column;
      border-radius: var(--border-radius-model);
      overflow: hidden;
      .header {
        width: 100%;
        position: relative;
        height: 58px;
        background-color: rgba(244, 244, 244, 1);
        padding: 0 30px;
        box-shadow: var(--default-box-shadow-down);
        z-index: 11;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        .title {
          font-style: 14px;
        }
        .close-btn {
          font-size: 30px;
          &:hover {
            cursor: pointer;
          }
        }
      }
      .main {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        background-color: #fff;
        border-radius: var(--border-radius-model);
        overflow: hidden;
        .body {
          display: flex;
          flex-direction: row;
          // height: calc(100% - $top-height);
          height: 100%;
          padding: 0 5px 5px 5px;
          .center {
            flex-grow: 1;
            border: 1px solid #ccc;
            border-top: none;
          }
          .right {
            width: 80px;
            padding: 10px;
            // display: grid;
            // grid-template-columns: 1fr;
            // grid-gap: 10px;
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            .button {
              width: 60px;
              height: 60px;
              border-radius: 10px;
              border: 1px solid #ccc;
              text-align: center;
              line-height: 60px;
              user-select: none;
              cursor: pointer;
              &:hover {
                border: 1px solid blue;
              }
              &:active {
                transform: translateY(2px) scale(0.98);
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
              }
            }

            .disabled {
              color: #ccc;
              cursor: not-allowed;
              &:hover {
                border: 1px solid #ccc;
              }
            }
          }
        }
      }
    }
  }
}
::v-deep .ivu-tabs {
  height: 100%;
  .ivu-tabs-bar {
    margin-bottom: 0;
  }
  .ivu-tabs-content {
    height: 96%;
    .tabContaniner {
      height: 100%;
    }
  }
}
</style>
